package cc.linker.steplink.crm.merchant.service.impl;

import cc.linker.steplink.crm.commons.BeanMapUtils;
import cc.linker.steplink.crm.commons.Constants;
import cc.linker.steplink.crm.commons.FeeConstants;
import cc.linker.steplink.crm.commons.TradeTypeConstants;
import cc.linker.steplink.crm.commons.constant.ContentConstant;
import cc.linker.steplink.crm.commons.constant.TlPayConstant;
import cc.linker.steplink.crm.commons.constant.WcPayConstant;
import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.model.SystemProperties;
import cc.linker.steplink.crm.commons.model.WcPayProperties;
import cc.linker.steplink.crm.commons.service.CommonsService;
import cc.linker.steplink.crm.commons.utils.CalendarUtils;
import cc.linker.steplink.crm.commons.utils.NumberUtils;
import cc.linker.steplink.crm.commons.utils.TransactionOrderUtil;
import cc.linker.steplink.crm.merchant.dao.acs.XbMerchantMapper;
import cc.linker.steplink.crm.merchant.pojo.AccountSummaryPo;
import cc.linker.steplink.crm.merchant.pojo.BindBankInfoPo;
import cc.linker.steplink.crm.merchant.pojo.CustomerAccountPo;
import cc.linker.steplink.crm.merchant.pojo.TransactionDetailsPo;
import cc.linker.steplink.crm.merchant.service.acs.XbMerchantService;
import cc.linker.steplink.crm.merchanth5.dao.acs.MerchantWalletDao;
import cc.linker.steplink.crm.merchanth5.dao.acs.PurchaseProcessDao;
import cc.linker.steplink.crm.merchanth5.dao.acs.WithdrawTaskDao;
import cc.linker.steplink.crm.merchanth5.pojo.WithdrawTaskPo;
import cc.linker.steplink.crm.merchanth5.service.MaiBaoLaService;
import cc.linker.steplink.crm.merchanth5.service.MallService;
import cc.linker.steplink.crm.merchanth5.service.acs.MerchantSalerService;
import cc.linker.steplink.crm.merchanth5.service.acs.MerchantWalletService;
import cc.linker.steplink.crm.response.GlobalException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @Description: 联盟商家service
 * @Author: 锋
 * @Date: 2019/9/23 19:30
 * @Version: 1.9.1
 */
@Slf4j
@Service
public class XbMerchantServiceImpl implements XbMerchantService {

    @Autowired
    private HttpService httpService;
    @Autowired
    private XbMerchantMapper xbMerchantMapper;
    @Autowired
    private PurchaseProcessDao purchaseProcessDao;
    @Autowired
    private WcPayProperties wcPayProperties;
    @Autowired
    private CommonsService commonsService;
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private MallService mallService;
    @Autowired
    private MaiBaoLaService maiBaoLaService;
    @Autowired
    private MerchantWalletService merchantWalletService;
    @Autowired
    private WithdrawTaskDao withdrawTaskDao;
    @Autowired
    private MerchantWalletDao merchantWalletDao;
    @Autowired
    private MerchantSalerService merchantSalerService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Map<String, Object> getAccountInfo(String adminId, String orgId) throws Exception {
        //根据 CAS_USER_ID 获取 CUSTOMER_ID
        Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
        if (shopInfo == null) {
            //大B用戶
            return xbMerchantMapper.getDmAccountInfo(orgId);
        } else {
            return xbMerchantMapper.getXbAccountInfo(shopInfo.get("customerId").toString());
        }
    }

    @Override
    public Map<String, Object> getShopInfo(String adminId) {
        return xbMerchantMapper.getShopInfo(adminId);
    }

    @Override
    public BindBankInfoPo getBindBankInfo(Map<String, String> map) throws Exception {
        BindBankInfoPo bankInfoPo = new BindBankInfoPo();
        //根据 CAS_USER_ID 获取 CUSTOMER_ID
        if (!"LINKER".equals(map.get("customerId"))) {
            Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(map.get("adminId"));
            if (shopInfo == null) {
                //大麦
                map.put("customerId", map.get("orgId"));
                map.put("customerType", "12");
                bankInfoPo = xbMerchantMapper.getBindBankInfo(map.get("orgId"), "1", null);
            } else {
                //联盟商家（小B）
                String customerId = shopInfo.get("customerId").toString();
                map.put("customerId", customerId);
                map.put("customerType", "11");
                bankInfoPo = xbMerchantMapper.getBindBankInfo(map.get("orgId"), "2", customerId);
            }
        } else {
            throw GlobalException.build("联汇资金账户 无银行卡");
//            //联汇资金账户
//            CustomerAccountPo customerAccountPo = xbMerchantMapper.getLinkerAccountInfo("LINKER");
//            if (customerAccountPo != null) {
//                bankInfoPo = xbMerchantMapper.getBindBankInfo(customerAccountPo.getCustomerId());
//            }
        }
        if (bankInfoPo == null || StringUtils.isEmpty(bankInfoPo.getBankId())) {
            bankInfoPo = new BindBankInfoPo();
            bankInfoPo.setStatus(0);
        } else {
            Integer withDrawNum = xbMerchantMapper.ifExistWithdraw(map);
            if (withDrawNum > 0) {
                bankInfoPo.setStatus(6);
            }
        }
        return bankInfoPo;
    }

    //@param map   adminId:用户ID PC端的，orgId当前机构号  withdrawAmount提现金额
    @Override
    public Object withdraw(Map<String, Object> map) throws Exception {
        String adminId = map.get("adminId").toString();
        String orgId = map.get("orgId").toString();

        //获取当前支付模式
        Integer payMode = mallService.getPayModeByOrgId(orgId);

        //region 获取提现金额
        String stringWithdrawAmount = map.get("withdrawAmount").toString();
        BigDecimal bigDecimal = new BigDecimal(stringWithdrawAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        BigDecimal multiply = bigDecimal.multiply(new BigDecimal(100));
        Long withdrawAmount = multiply.longValue();
        //endregion

        //获取店铺信息
        Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
        //账户余额(分)
        Long balance = 0L;
        //订单号
        String orderNo = TransactionOrderUtil.TYPE_WITHDRAW + TransactionOrderUtil.getPrimaryKey();
        //提现单号
        String withdrawNo = "D" + System.currentTimeMillis();
        //是否小B
        String ifxb = "1";
        //银行卡数据
        BindBankInfoPo bankInfoPo = null;
        //获取提现的设置
        Map<String, Object> withdrawSet = xbMerchantMapper.getWithdrawLimit(orgId);
        //提现用户ID
        String withdrawCustomerId;
        //记录下的用户ID
        String recordCustomerId;
        //提现手续费
        Long withdrawFee = 0L;
        //实际到账金额
        Long realWithdraw = 0L;

        //如果有店铺设置，那么就是联盟商家（小B）
        if (shopInfo != null) {
            //小B使用customerId
            String shopInfoCustomerId = shopInfo.get("customerId").toString();
            withdrawCustomerId = purchaseProcessDao.getAccountUidByCustomerId(shopInfoCustomerId);
            recordCustomerId = shopInfoCustomerId;
            bankInfoPo = xbMerchantMapper.getBindBankInfo(orgId, "2", shopInfoCustomerId);

            // region如果没获取到银行卡直接返回
            if (bankInfoPo == null) {
                throw GlobalException.build("请先绑定银行卡");
            }
            //endregion

            withdrawNo = withdrawNo + shopInfoCustomerId;
            Map<String, Object> wallet = xbMerchantMapper.getXbAccountInfo(shopInfoCustomerId);
            if (wallet != null) {
                balance = Long.valueOf(wallet.get("customerBalance").toString());
            }

            //region 小B提现需要提现手续费
            if (withdrawSet != null) {
                Long minWithdraw = Long.valueOf(withdrawSet.get("withdrawLimit").toString());
                if (withdrawAmount < minWithdraw) {
                    double v = minWithdraw.doubleValue() / 100;
                    String withdrawLimit = new BigDecimal(v).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
                    throw GlobalException.build("至少提现" + withdrawLimit + "元");
                }
                //通联模式下需要获取提现手续费
                if (payMode == 2 || payMode == 3) {
                    //按比例收取
                    if (Integer.valueOf(withdrawSet.get("takeType").toString()) == 1) {
                        double withdrawRate = withdrawAmount * Double.valueOf(withdrawSet.get("withdrawRate").toString()) / 100;
                        withdrawFee = new BigDecimal(withdrawRate).setScale(0, BigDecimal.ROUND_HALF_EVEN).longValue();
                    } else {
                        //按固定金额收取
                        withdrawFee = Long.valueOf(withdrawSet.get("withdrawCost").toString());
                        if (withdrawAmount < withdrawFee) {
                            throw GlobalException.build("请大于手续费");
                        }
                    }
                    //实际到账金额 = 总提现金额 - 提现手续费
                    realWithdraw = withdrawAmount - withdrawFee;
                }
            }
            //endregion
        } else { //大B提现
            recordCustomerId = orgId;
            withdrawCustomerId = purchaseProcessDao.getAccountUidByOrgId(orgId);
            bankInfoPo = xbMerchantMapper.getBindBankInfo(orgId, "1", null);
            // region如果没获取到银行卡直接返回
            if (bankInfoPo == null) {
                throw GlobalException.build("请先绑定银行卡");
            }
            //endregion
            //大B
            ifxb = "0";
            withdrawNo = withdrawNo + orgId;
            //获取大B余额信息
            Map<String, Object> orgWallet = xbMerchantMapper.getOrgAccountInfo(orgId);
            balance = Long.valueOf(orgWallet.get("orgBalance").toString());
            realWithdraw = withdrawAmount;
        }
        // 查询头寸金额
        if(payMode == 2 || payMode == 3){
            //获取平台别名
            String clintType = payMode == 3 ?  maiBaoLaService.getAliasByLinker() : maiBaoLaService.getAlias(orgId);
            Long reserveFundBalance = merchantWalletService.queryReserveFundBalance(clintType);
            if(withdrawAmount>reserveFundBalance){
                throw GlobalException.build("暂时无法提现");
            }
        }

        //region 如果输入金额超过余额
        if (withdrawAmount > balance) {
            throw GlobalException.build("输入金额超过余额");
        }
        //endregion

        //手续费给谁
        //String feeId = purchaseProcessService.getCustomerIdByFeeTypeAndOrdId(FeeConstants.HANDLING_FEE, orgId,payMode);

        //region 定义提现记录map
        Map<String, Object> insertWithdrawMap = new HashMap<>();
        String accountType = purchaseProcessDao.getAccountByFeeTypeAndOrdId(FeeConstants.RECOMMEND_FEE, orgId);
        switch (accountType) {
            case "A":
                insertWithdrawMap.put("receiveRole", 0);
                break;
            case "B":
                insertWithdrawMap.put("receiveRole", 1);
                break;
            default:
                break;
        }
        insertWithdrawMap.put("busiNo", withdrawNo);
        insertWithdrawMap.put("customerId", recordCustomerId);
        insertWithdrawMap.put("status", 0);
        insertWithdrawMap.put("bankId", bankInfoPo.getBankId());
        insertWithdrawMap.put("bankAccountNumber", bankInfoPo.getBankCardCode());
        insertWithdrawMap.put("withdrawAmount", withdrawAmount);
        insertWithdrawMap.put("realWithdraw", realWithdraw);
        insertWithdrawMap.put("serialNumber", "");
        insertWithdrawMap.put("orgId", orgId);

        //insertWithdrawDetail下需要的参数
        insertWithdrawMap.put("balance", balance);
        insertWithdrawMap.put("orderNo", orderNo);
        //insertWithdrawFeeDetail下需要的参数
        insertWithdrawMap.put("withdrawFee", withdrawFee);
        insertWithdrawMap.put("feeCustomerId", orgId);
        insertWithdrawMap.put("ifxb",ifxb);
        //endregion

        //微信提现
        if (payMode == 1) {
            xbMerchantMapper.insertWithdrawRecord(insertWithdrawMap);
            if (ifxb.equals("1")) {
                xbMerchantMapper.updateXbBalance(withdrawAmount, recordCustomerId);
                insertWithdrawMap.put("payRole", 2);
            } else {
                xbMerchantMapper.updateOrgBalance(withdrawAmount, orgId);
                insertWithdrawMap.put("payRole", 1);
            }
            xbMerchantMapper.insertWithdrawDetail(insertWithdrawMap);
            xbMerchantMapper.insertWithdrawFeeDetail(insertWithdrawMap);
            return null;
        } else if (payMode == 2 || payMode == 3) {

            //region 定义提现实体
            String industryCode = purchaseProcessDao.getOrgMerchantInfoByOrgId(orgId);// 行业代码
            String industryName = purchaseProcessDao.getIndustryNameByCode(industryCode); // 行业名称
            WithdrawTaskPo withdrawTaskPo = new WithdrawTaskPo();
            withdrawTaskPo.withdrawId = UUID.randomUUID().toString();
            withdrawTaskPo.customerId = withdrawCustomerId;
            withdrawTaskPo.withdrawCode = withdrawNo; //提现记录ID对应提现表
            withdrawTaskPo.withdrawMoney = withdrawAmount;
            withdrawTaskPo.serviceMoney = withdrawFee;
            withdrawTaskPo.receiveMoney = realWithdraw;
            withdrawTaskPo.amount = withdrawAmount;
            withdrawTaskPo.appId = purchaseProcessDao.getAppIdByOrgId(orgId);
            withdrawTaskPo.industryCode = !StringUtils.isEmpty(industryCode) ? industryCode : "";
            withdrawTaskPo.industryName = !StringUtils.isEmpty(industryName) ? industryName : "";
            withdrawTaskPo.source = 2;
            withdrawTaskPo.clientType = payMode == 3 ? maiBaoLaService.getAliasByLinker() :  maiBaoLaService.getAlias(orgId);
            withdrawTaskPo.validateType = 0;
            withdrawTaskPo.fee = 0L;
            withdrawTaskPo.feeCustomerId = orgId;
            withdrawTaskPo.orderSn = orderNo;
            withdrawTaskPo.remark = "";
            withdrawTaskPo.orgId = orgId;
            withdrawTaskPo.status = 0;
            withdrawTaskPo.billMapJson = JSON.toJSONString(insertWithdrawMap);
            withdrawTaskPo.isUserTransfer=1;
            withdrawTaskPo.isServiceTransfer=1;
            withdrawTaskPo.customerOrderSn="";
            withdrawTaskPo.serviceOrderSn="";
            //endregion

            //region 判断当前时间是否在银行可提现时间内，如果是那么提现，如果不是记录数据库任务在允许时间进行提现
            Date now = new Date();
            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
            String nowDate = format.format(now);
            //如果是在可提现范围之内
            String startDate = map.containsKey("startDate") ? map.get("startDate").toString() : "07:15:00";
            String endDate = map.containsKey("endDate") ? map.get("endDate").toString() : "19:45:00";
            if (CalendarUtils.isEffectiveDate(nowDate, startDate, endDate)) {
                //进行提现
                return this.sendWithdaw(insertWithdrawMap, withdrawTaskPo, false);
            } else {
                //如果是不在可提现范围之内
                //添加提现任务
                withdrawTaskDao.addWithdrawTask(withdrawTaskPo);
                //region 记录账单
                insertWithdrawMap.put("status", 0);
                insertWithdrawMap.put("serialNumber", "");
                //记账等操作
                this.insertBill(insertWithdrawMap, withdrawTaskPo);
                //endregion
                return true;
            }
            //endregion
        } else {
            throw GlobalException.build("机构支付模式设置错误");
        }
    }

    //发送提现
    @Override
    public Boolean sendWithdaw(Map<String, Object> insertWithdrawMap,WithdrawTaskPo withdrawTaskPo,Boolean isTask) {
        try {
            // 通联
            withdrawTaskPo.amount = withdrawTaskPo.receiveMoney;
            withdrawTaskPo.remark = StringUtils.isEmpty(withdrawTaskPo.remark) ? "":withdrawTaskPo.remark;
            withdrawTaskPo.clintType = withdrawTaskPo.clientType;
            LOGGER.info("pc-sendWithdaw--request:"+JSONObject.toJSONString(withdrawTaskPo));
            String url = wcPayProperties.getAcsurl() + TlPayConstant.TRADE_CASE_WITHDRAWAL;
            String result = httpService.doPost(url, JSONObject.toJSONString(withdrawTaskPo), WcPayConstant.JSON);
            LOGGER.info("pc-sendWithdaw--response:"+result);
            JSONObject object = JSONObject.parseObject(result);
            if (object != null) {
                if (("200").equals(object.getString("code"))) {
                    JSONObject data = JSONObject.parseObject(object.getString("data"));
                    if (("30").equals(data.getString("status"))) {
                        //成功 更新提现记录状态
                        insertWithdrawMap.put("status", 2);
                    } else if (("10").equals(data.getString("status"))) {
                        // 银行处理中
                        insertWithdrawMap.put("status", 1);
                    } else {
                        if (isTask) return false;
                        throw GlobalException.build("提现失败");
                    }
                    if(!isTask) {
                        //region调用接口返回后做的事情
                        insertWithdrawMap.put("serialNumber", data.getString("txsn"));
                        //记账等操作
                        this.insertBill(insertWithdrawMap,withdrawTaskPo);
                    }else{
                        //更新提现状态
                        //修改提现的当前状态
                        merchantWalletDao.updateWithDrawStatus(withdrawTaskPo.withdrawCode,  insertWithdrawMap.get("status").toString());
                    }
                    //endregion
                    return true;
                } else {
                    if (isTask) {
                        return false;
                    } else {
                        throw GlobalException.build("提现失败：" + object.get("msg").toString());
                    }
                }
            } else {
                if (isTask) {
                    return false;
                } else {
                    throw GlobalException.build("提现失败");
                }
            }
        } catch (Exception ex) {
            LOGGER.info("PC提现失败----", ex.getStackTrace().toString());
            if (isTask) {
                return false;
            } else {
                throw GlobalException.build("提现失败");
            }
        }
    }

    //记录账单
    private void insertBill(Map<String,Object> insertWithdrawMap,WithdrawTaskPo withdrawTaskPo) {
        xbMerchantMapper.insertWithdrawRecord(insertWithdrawMap);
        //如果是小B 模式
        if (insertWithdrawMap.get("ifxb").toString().equals("1")) {
            xbMerchantMapper.updateXbBalance(withdrawTaskPo.withdrawMoney, insertWithdrawMap.get("customerId").toString());
            insertWithdrawMap.put("payRole", 2);
        } else {
            xbMerchantMapper.updateOrgBalance(withdrawTaskPo.withdrawMoney, withdrawTaskPo.orgId);
            insertWithdrawMap.put("payRole", 1);
        }
        xbMerchantMapper.insertWithdrawDetail(insertWithdrawMap);

        Map<String,Object> map = new HashMap<>();
        map.put("withdrawTaskPo",withdrawTaskPo);
        map.put("addServiceBillMap",insertWithdrawMap);
        stringRedisTemplate.opsForValue().set("withdraw:serviceBill" + withdrawTaskPo.withdrawCode, JSON.toJSONString(map));
//        xbMerchantMapper.insertWithdrawFeeDetail(insertWithdrawMap);
    }

    @Override
    public String checkBankSendMoney(Map<String, Object> map) throws Exception {
        if (!map.containsKey("customerId") || !map.get("customerId").toString().startsWith("LINKER")) {
            Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(map.get("adminId").toString());
            if (shopInfo == null) {
                //大B
                map.put("customerId", map.get("orgId"));
            } else {
                //小b
                map.put("customerId", Constants.XB_PREFIX.concat(shopInfo.get("customerId").toString()));
            }
        } else {
            CustomerAccountPo customerAccountPo = xbMerchantMapper.getLinkerAccountInfo("LINKER");
            if (customerAccountPo != null) {
                //联汇资金账户
                map.put("customerId", customerAccountPo.getCustomerId());
                //联汇资金账户类型为12 企业用户
                map.put("customerType", "12");
            } else {
                throw GlobalException.build("未开户");
            }
        }
        map.put("verifyWay", 20);
        map.put("verifyInfo", map.get("sendMoney"));
        //String result = "{\"code\": \"200\",\"data\": \"成功\",\"msg\": \"成功\"}";
        String result = httpService.doPost(wcPayProperties.getAcsurl() + WcPayConstant.USER_BANK_ACTIVE_PAY, JSONObject.toJSONString(map), WcPayConstant.JSON);
        JSONObject object = JSONObject.parseObject(result);
        if (object != null) {
            if (("200").equals(object.get("code").toString())) {
                //中金返回验证成功
//                map.put("bankStatus", "30");
//                xbMerchantMapper.updateBindBankInfo(map);
//                Map<String,Object> accountParams = new HashMap<>();
//                accountParams.put("bkaccBindStatus", "2");
//                accountParams.put("customerId", map.get("customerId"));
//                accountParams.put("orgId", map.get("orgId"));
//                platformSetNameDao.capitalAccountUpdate(accountParams);
                return object.get("data").toString();
            } else {
                //中金返回验证成功
//                map.put("bankStatus", "40");
//                xbMerchantMapper.updateBindBankInfo(map);
                throw GlobalException.build(object.get("msg").toString());
            }
        } else {
            throw GlobalException.build("校验打款金额失败");
        }
    }

    @Override
    public String bankCardBind(Map<String, String> map) throws Exception {
        String adminId = map.get("adminId");
        String orgId = map.get("orgId");
        String customerId = "";
        String type = "";
        String id = "";
        Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
        CustomerAccountPo customerAccountPo;
        if (!"LINKER".equals(map.get("customerId"))) {
            if (shopInfo != null) {
                // 小B账户类型为11 联盟商家
                map.put("customerType", "12");
                map.put("customerId", shopInfo.get("customerId").toString());
                type = "2";
                customerId = shopInfo.get("customerId").toString();
            } else {
                //大B使用机构ID绑定
                map.put("customerId", map.get("orgId"));
                //大B账户类型为12 企业用户
                map.put("customerType", "12");
                type = "1";
            }
            id = xbMerchantMapper.getMerchantId(type, customerId, orgId);
            Map<String, String> accParam = new HashMap<>();
            accParam.put("customerId", id);
            customerAccountPo = xbMerchantMapper.getCustomerAccount(accParam);
        } else {
            throw GlobalException.build("联汇资金账户 无需绑定银行卡");
//            customerAccountPo = xbMerchantMapper.getLinkerAccountInfo("LINKER");
//            if (customerAccountPo != null) {
//                //联汇资金账户
//                map.put("customerId", customerAccountPo.getCustomerId());
//                //联汇资金账户类型为12 企业用户
//                map.put("customerType", "12");
//            }
        }
        Integer withDrawNum = xbMerchantMapper.ifExistWithdraw(map);
        if (withDrawNum > 0) {
            throw GlobalException.build("提现中，无法绑定");
        }
        //调用中金接口
        Map<String, Object> params = new HashMap<>();
        //绑卡请求银行卡名称，如果是个人填写真实姓名，如果是企业，填写企业名字
        if ("11".equals(customerAccountPo.getCustomerType())) {
            params.put("bankAccountName", customerAccountPo.getCustomerName());
        } else {
            params.put("bankAccountName", customerAccountPo.getCorporationName());
        }
        params.put("bankAccountNumber", map.get("bankAccountNumber"));
        params.put("bankId", map.get("bankId"));
        params.put("bankPhoneNumber", "");
        params.put("branchName", "");
        params.put("clintType", maiBaoLaService.getAlias(orgId));
        params.put("customerId", id);
        params.put("cvn2", "");
        params.put("unionBank", "");
        params.put("validDate", "");
        //String result = "{\"code\": \"200\",\"data\": \"成功\",\"msg\": \"成功\"}";
        String url = wcPayProperties.getAcsurl() + WcPayConstant.USER_BANK_BIND_PAY;
        //String url = "https://crmhd.linker.cc/payway" + WcPayConstant.USER_BANK_BIND_PAY;
        String result = httpService.doPost(url, JSONObject.toJSONString(params), WcPayConstant.JSON);
        JSONObject object = JSONObject.parseObject(result);
        if (object != null) {
            if (("200").equals(object.get("code").toString())) {
                return object.get("data").toString();
            } else {
                throw GlobalException.build(object.get("msg").toString());
            }
        } else {
            throw GlobalException.build("绑定失败");
        }
    }

    @Override
    public String bankCardChange(Map<String, String> map) throws Exception {
        String adminId = map.get("adminId");
        String orgId = map.get("orgId");
        String customerId = "";
        String type = "";
        String id = "";
        Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
        CustomerAccountPo customerAccountPo;
        if (!"LINKER".equals(map.get("customerId"))) {
            if (shopInfo != null) {
                // 小B账户类型为11 联盟商家
                map.put("customerType", "12");
                map.put("customerId", shopInfo.get("customerId").toString());
                type = "2";
                customerId = shopInfo.get("customerId").toString();
            } else {
                //大B使用机构ID绑定
                map.put("customerId", map.get("orgId"));
                //大B账户类型为12 企业用户
                map.put("customerType", "12");
                type = "1";
            }
            id = xbMerchantMapper.getMerchantId(type, customerId, orgId);
            Map<String, String> accParam = new HashMap<>();
            accParam.put("customerId", id);
            customerAccountPo = xbMerchantMapper.getCustomerAccount(accParam);
        } else {
            throw GlobalException.build("联汇资金账户 无需绑定银行卡");
        }
        if(customerAccountPo==null){
            throw GlobalException.build("该商户未认证！");
        }
        Integer withDrawNum = xbMerchantMapper.ifExistWithdraw(map);
        if (withDrawNum > 0) {
            throw GlobalException.build("提现中，无法绑定");
        }
        //调用中金接口
        Map<String, Object> params = new HashMap<>();
        //绑卡请求银行卡名称，如果是个人填写真实姓名，如果是企业，填写企业名字
        if ("11".equals(customerAccountPo.getCustomerType())) {
            params.put("bankAccountName", customerAccountPo.getCustomerName());
        } else {
            params.put("bankAccountName", customerAccountPo.getCorporationName());
        }
        params.put("bankAccountNumber", map.get("bankAccountNumber"));
        params.put("bankId", map.get("bankId"));
        params.put("bankPhoneNumber", map.get("bankPhoneNumber"));
        params.put("clintType", maiBaoLaService.getAlias(orgId));
        params.put("customerId", id);
        String url = wcPayProperties.getAcsurl() + WcPayConstant.USER_BANK_BIND_PAY;
        String result = httpService.doPost(url, JSONObject.toJSONString(params), WcPayConstant.JSON);
        JSONObject object = JSONObject.parseObject(result);
        if (object != null) {
            if (("200").equals(object.get("code").toString())) {
                return object.get("data").toString();
            } else {
                //throw GlobalException.build(object.get("msg").toString());
                LOGGER.error(object.get("msg").toString());
                throw GlobalException.build("换绑失败");
            }
        } else {
            throw GlobalException.build("换绑失败");
        }
    }

    @Override
    public List<TransactionDetailsPo> getTransactionDetails(Map<String, Object> params) {
        String salerId = "";
        if(!StringUtils.isEmpty(params.get("salerId"))){
            salerId = params.get("salerId").toString();
        }
        List<TransactionDetailsPo> transactionDetails = xbMerchantMapper.getTransactionDetails(params);
        for (TransactionDetailsPo po : transactionDetails) {
            Integer tradeType = po.getTradeType();
            if (TradeTypeConstants.TRADE_SERVER_FEE.equals(tradeType) || TradeTypeConstants.REJUVENATE_FEE.equals(tradeType)
            || TradeTypeConstants.PURCHASE_FEE.equals(tradeType) || TradeTypeConstants.INSPECT_SHARE_FEE.equals(tradeType)
            || TradeTypeConstants.CLOTHES_ENUCLEATE_FEE.equals(tradeType) || TradeTypeConstants.INSPECT_REFUND_FEE.equals(tradeType)
            || TradeTypeConstants.INSPECT_ONLINE_SHARE_FEE.equals(tradeType) || TradeTypeConstants.WITHDRAWAL_FEE.equals(tradeType)) {
                po.setType(0);
            } else if (tradeType > 30) {
                    //懂小姐30以后
            }

            if (TradeTypeConstants.SPREAD_FEE.equals(tradeType)) {
                //推广佣金
                if(salerId.equals(po.getPayUser())){
                    po.setType(0);
                }
            }
            if (po.getTradeSumCent() != null) {
                double tradeSum = ((double) po.getTradeSumCent() / 100);
                po.setTradeSum(tradeSum);
            }
//            if(po.getPayInfo().startsWith("Y")){
//                po.setTradeType(20);
//            }
        }
        return transactionDetails;
    }

    @Override
    public void exportTransactionDetails (Map<String, Object> param, HttpServletResponse response) throws Exception {
        String[] title = {"类型", "入账时间", "名称", "订单号", "账户", "收支类型", "金额（元）", "支付方式"};
        String fileName = "";
        if(StringUtils.isEmpty(param.get("startTime")) || StringUtils.isEmpty(param.get("endTime"))){
            fileName = "账单明细";
        }else{
            fileName = "账单明细("+param.get("startTime").toString().substring(0,10)+"-"+param.get("endTime").toString().substring(0,10)+")";
        }
        // -1-全部，0-提现，1-商品成交，4-平台抽成，6-联盟商家开通，8-加盟代理开通，13-退款
        //         0-提现，1-商品成交，6-联盟商家开通，8-加盟代理开通，13-退款
        String[] strings = {"tradeName", "tradeTime", "name", "payInfo", "chatType", "tranType", "tradeSum","tradeInfo"};
        List<Map<String, Object>> list1 = new ArrayList<>();
        List<TransactionDetailsPo> list = getTransactionDetails(param);
        list.forEach(x->{
            Map<String,Object> temp = BeanMapUtils.beanToMap(x);
            // 类型转化
            String tradeType = temp.get("tradeType").toString();
            String tradeName = "";
            String tradeInfo = StringUtils.isEmpty(temp.get("tradeOrderNum"))?"":"微信"+temp.get("tradeOrderNum").toString();
            switch(tradeType){
                case "0":
                    tradeName = "提现";
                    tradeInfo = "无";
                    break;
                case "1":
                    tradeName = "商品成交";
                    break;
                case "4":
                    tradeName = "平台抽成";
                    break;
                case "6":
                    tradeName = "联盟商家开通";
                    break;
                case "8":
                    tradeName = "加盟代理开通";
                    break;
                case "11":
                    tradeName = "提现抽成";
                    break;
                case "12":
                    tradeName = "提现失败";
                    tradeInfo = "无";
                    break;
                case "13":
                    tradeName = "退款";
                    break;
                case "14":
                    tradeName = "推广佣金";
                    break;
                case "15":
                    tradeName = "交易手续费";
                    break;
                case "16":
                    tradeName = "创作奖励";
                    break;
                case "17":
                    tradeName = "返润佣金";
                    break;
                case "18":
                    tradeName = "采购";
                    break;
                case "19":
                    tradeName = "支付抽成";
                    break;
                case "20":
                    tradeName = "报名表单";
                    break;
                case "21":
                    tradeName = "会员开通";
                    break;
                case "31":
                    tradeName = "体检费用";
                    break;
                case "32":
                    tradeName = "体检分佣";
                    break;
                case "33":
                    tradeName = "体检充值";
                    break;
                case "34":
                    tradeName = "服饰券核销";
                    break;
                case "35":
                    tradeName = "用户体检返还";
                    break;
                case "39":
                    tradeName = "线上体检";
                    break;
                case "40":
                    tradeName = "线上体检分佣";
                    break;
                case "41":
                    tradeName = "加盟费";
                    break;
                default:
                        break;
            }
            temp.put("tradeName",tradeName);
            // 入账时间
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sDate=sdf.format(temp.get("tradeTime"));
            temp.put("tradeTime",sDate);
            // 账户
            temp.put("chatType","店铺收支");
            // 收支类型
            String tranType = "收入";
            if(!StringUtils.isEmpty(temp.get("type"))){
                if("0".equals(temp.get("type").toString())){
                    tranType = "支出";
                }
            }
            temp.put("tranType",tranType);
            // 支付方式
            temp.put("tradeInfo",tradeInfo);
            list1.add(temp);
        });
        commonsService.excelDownload(list1, strings, title, fileName, response);
    }

    @Override
    public List<AccountSummaryPo> getAccountSummary(Map<String, Object> params) {
        List<AccountSummaryPo> accountSummaryPoList;
        String scale = (String) params.get("scale");
        Integer customerType = (Integer) params.get("customerType");
        // 联盟商家
        if ("month".equals(scale)) {
            if (customerType == 2) {
                //大B
                accountSummaryPoList = xbMerchantMapper.getAccountSummaryByDay(params);
            } else {
                //小B
                accountSummaryPoList = xbMerchantMapper.getAccountSummarySalerByDay(params);
            }
        } else if ("year".equals(scale)) {
            if (customerType == 2) {
                //大B
                accountSummaryPoList = xbMerchantMapper.getAccountSummaryByMonth(params);
            } else {
                //小B
                accountSummaryPoList = xbMerchantMapper.getAccountSummarySalerByMonth(params);
            }
        } else {
            throw GlobalException.build("格式非法");
        }
        accountSummaryPoList.forEach(po -> {
                    //分转元
                    po.setPaySummary(NumberUtils.fenToYuan(po.getPaySummaryCent()));
                    po.setIncomeSummary(NumberUtils.fenToYuan(po.getIncomeSummaryCent()));
                    po.setBalance(NumberUtils.fenToYuan(po.getBalanceCent()));
                }
        );
        return accountSummaryPoList;
    }

    @Override
    public Map<String, Object> getAccountDetail(Map<String, Object> map) {
        Map<String, Object> resultMap = new HashMap<>();
        Boolean sales = (Boolean) map.get("sales");
        String date = (String) map.get("date");
        if (sales) {
            // 小b
            String adminId = (String) map.get("adminId");
            Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
            map.put("customerId", shopInfo.get("customerId"));
            String shopName = xbMerchantMapper.getShopName(map);
            map.put("receiveRole", 2);
            resultMap.put("shopName", shopName);
        } else {
            // 大b
            map.put("customerId", map.get("orgId"));
            String shopName = xbMerchantMapper.getShopName(map);
            map.put("receiveRole", 1);
            resultMap.put("shopName", shopName);
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        if (date.length() == 7) {
            // 月
            map.put("day", date + "-01");
            map.put("interval", "MONTH");
            map.put("format", "%Y-%m");
            String start = date + "-01";
            String end = LocalDate.parse(start, df).with(TemporalAdjusters.lastDayOfMonth()).format(df);
            start += " 00:00:00";
            end += " 23:59:59";
            resultMap.put("cycle", start + "至" + end);
        } else if (date.length() == 10) {
            // 日
            map.put("day", date);
            map.put("interval", "DAY");
            map.put("format", "%Y-%m-%d");
            String start = date + " 00:00:00";
            String end = date + " 23:59:59";
            resultMap.put("cycle", start + "至" + end);
        } else {
            throw GlobalException.build("日期格式不正确");
        }
        Map<String, Object> balance = xbMerchantMapper.getBalanceByDateAndCustomerId(map);
        if (balance == null) {
            balance = xbMerchantMapper.getEndBalance(map);
            if (balance == null) {
                balance = new HashMap<>();
                balance.put("endBalance", 0);
                balance.put("freeze", 0);
            }
            balance.put("balance", 0);
        }
        Map<String, Object> incomeAndExpenditure = xbMerchantMapper.getIncomeAndExpenditure(map);
        if (incomeAndExpenditure != null) {
            balance.putAll(incomeAndExpenditure);
        } else {
            balance.put("pay", 0);
            balance.put("receive", 0);
        }

        // 格式化
        for (String s : balance.keySet()) {
            double v = Integer.valueOf(balance.get(s).toString()).doubleValue() / 100;
            String y = new BigDecimal(v).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
            balance.put(s, y);
        }

        resultMap.put("balance", balance);

        // 收入
        List<Map<String, Object>> income = xbMerchantMapper.getIncomeOverTime(map);
        this.statisticsList(income);
        resultMap.put("income", income);

        // 支出
        List<Map<String, Object>> expenditure = xbMerchantMapper.getExpenditureOverTime(map);
        if (expenditure.size() == 1 && expenditure.get(0).get("sum") == null) {
            expenditure = new ArrayList<>();
        }
        this.statisticsList(expenditure);
        resultMap.put("expenditure", expenditure);

        return resultMap;
    }

    private void statisticsList(List<Map<String, Object>> list) {
        if (list == null) {
            list = new ArrayList<>();
        } else if (list.size() != 0) {
            Integer sum = 0;
            Integer count = 0;
            for (Map<String, Object> objectMap : list) {
                sum += Integer.valueOf(objectMap.get("sum").toString());
                count += Integer.valueOf(objectMap.get("count").toString());
            }
            Map<String, Object> sumMap = new HashMap<>();
            sumMap.put("type", -1);
            sumMap.put("sum", sum);
            sumMap.put("count", count);
            list.add(sumMap);
        }

        for (Map<String, Object> map : list) {
            for (String s : map.keySet()) {
                if ("sum".equals(s)) {
                    double v = Integer.valueOf(map.get(s).toString()).doubleValue() / 100;
                    String y = new BigDecimal(v).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
                    map.put(s, y);
                }
            }
        }
    }

    //2019-10-10=2019年10月10日
    @Override
    public void downloadAccountDetail(Map<String, Object> map, HttpServletResponse response) throws Exception {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        Boolean sales = (Boolean) map.get("sales");
        String date = (String) map.get("date");
        if (sales) {
            // 小b
            String adminId = (String) map.get("adminId");
            Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(adminId);
            map.put("salerId", shopInfo.get("customerId"));
            map.put("customerType", 1);
        } else {
            // 大b
            map.put("salerId", map.get("orgId"));
            map.put("customerType", 2);
        }
        String fileName;
        if (date.length() == 7) {
            // 月
            String start = date + "-01";
            String end = LocalDate.parse(start, df).with(TemporalAdjusters.lastDayOfMonth()).format(df);
            start += " 00:00:00";
            end += " 23:59:59";
            map.put("startTime", start);
            map.put("endTime", end);
            fileName = date.replaceFirst("-", "年")
                    .concat("月");
        } else if (date.length() == 10) {
            // 日
            String end = LocalDate.parse(date, df).format(df);
            String start = date + " 00:00:00";
            end += " 23:59:59";
            map.put("startTime", start);
            map.put("endTime", end);
            fileName = date.replaceFirst("-", "年")
                    .replaceFirst("-", "月")
                    .concat("日");
        } else {
            throw GlobalException.build("日期格式不正确");
        }
        map.put("tradeType", -1);
        List<TransactionDetailsPo> list = this.getTransactionDetails(map);
        List<Map<String, Object>> resultMap = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        list.forEach(x -> {
            Integer tradeType = x.getTradeType();
            String tradeTypeName = this.getTradeTypeName(tradeType);
            Date tradeTime = x.getTradeTime();
            String formatTradeTime = sdf.format(tradeTime);
            Map<String, Object> bean = BeanMapUtils.beanToMap(x);
            bean.put("tradeTime", formatTradeTime);
            bean.put("account", "店铺收支");
            bean.put("type", x.getTradeSumCent() > 0 ? "收入" : "支出");
            bean.put("tradeType", tradeTypeName);
            bean.put("tradeOrderNum", StringUtils.isEmpty(bean.get("tradeOrderNum"))?"":"微信"+bean.get("tradeOrderNum"));
            resultMap.add(bean);
        });
        String[] title = {"类型", "入账时间", "业务单号", "账户", "收支类型", "金额(元)", "支付方式"};
        String[] key = {"tradeType", "tradeTime", "busiSn", "account", "type", "tradeSum", "tradeOrderNum"};
        fileName += "账务汇总详情";
        commonsService.excelDownload(resultMap, key, title, fileName, response);
    }

    @Override
    public Map<String, Object> getGuideInfo(Map<String, Object> map) {
        Map<String, Object> info = xbMerchantMapper.getShopGuideInfoByAdminId(map);
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("organizationNum", map.get("orgId"));
        reqMap.put("userId", map.get("adminId"));
        String url = systemProperties.getSync().getContentUrl() + ContentConstant.NEWS_BY_STEP;
//        String url = "https://hdmediapool.linker.cc/cloudMediaAI/mediaPool/list/newsByStep";
        String result;
        try {
            result = httpService.doPost(url, reqMap, ContentConstant.HEADER);
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
            throw GlobalException.build("内容库调用异常");
        }
        Map parse = (Map) JSON.parse(result);
        Integer count = Integer.valueOf(parse.get("count").toString());
        info.put("createArticle", count);
        return info;
    }

    private String getTradeTypeName(int tradeType) {
        String tradeName;
        switch (tradeType) {
            case 0:
                tradeName = "提现";
                break;
            case 1:
                tradeName = "商品成交";
                break;
            case 4:
                tradeName = "平台抽成";
                break;
            case 6:
                tradeName = "联盟商家开通";
                break;
            case 8:
                tradeName = "加盟代理开通";
                break;
            case 11:
                tradeName = "提现抽成";
                break;
            case 12:
                tradeName = "提现失败";
                break;
            case 13:
                tradeName = "退款";
                break;
            case 14:
                tradeName = "推广佣金";
                break;
            case 15:
                tradeName = "交易手续费";
                break;
            case 16:
                tradeName = "创作奖励";
                break;
            case 17:
                tradeName = "返润佣金";
                break;
            case 18:
                tradeName = "采购";
                break;
            case 19:
                tradeName = "支付抽成";
                break;
            case 20:
                tradeName = "报名表单";
                break;
            case 21:
                tradeName = "会员开通";
                break;
            case 31:
                tradeName = "体检费用";
                break;
            case 32:
                tradeName = "体检分佣";
                break;
            case 33:
                tradeName = "体检充值";
                break;
            case 34:
                tradeName = "服饰券核销";
                break;
            case 35:
                tradeName = "用户体检返还";
                break;
            case 39:
                tradeName = "线上体检";
                break;
            case 40:
                tradeName = "线上体检分佣";
                break;
            case 41:
                tradeName = "加盟费";
                break;
            default:
                tradeName = "";
                break;
        }
        return tradeName;
    }

    @Override
    public void displayGuide(Map<String, Object> map) {
        xbMerchantMapper.displayGuide(map);
    }

    @Override
    public Integer checkWithDraw(Map<String, Object> param) {
        if ((Boolean) param.get("ifSales")) {
            Map<String, Object> shopInfo = xbMerchantMapper.getShopInfo(param.get("adminId").toString());
            param.put("customerId", shopInfo.get("customerId"));
        } else {
            param.put("customerId", param.get("orgId"));
        }
        return xbMerchantMapper.checkWithDraw(param);
    }

    @Override
    public String getDongCustomerIdByUserId(String userId) {
        return xbMerchantMapper.getDongCustomerIdByUserId(userId);
    }

    @Override
    public PageInfo<Map<String, Object>> tradeList(Map<String, Object> params) {
        String customerId = params.get("customerId").toString();
        int pageIndex = Integer.parseInt(params.get("pageIndex").toString());
        int pageSize = Integer.parseInt(params.get("pageSize").toString());
        PageHelper.startPage(pageIndex, pageSize);
        List<Map<String, Object>> result = merchantSalerService.getOrderListFreeze(params);
        result.forEach(x -> {
//            Map<String, Object> ttp = xbMerchantMapper.getOrderInfo(x.get("orderSn").toString(),x.get("protectId").toString());
//            x.put("serialNo", ttp.get("serialNo"));
//            x.put("orderName", ttp.get("orderName"));
//            x.put("isEnd", ttp.get("isEnd"));

            String amount = x.get("amount") == null ? "0" : x.get("amount").toString();
            x.put("amount", NumberUtils.fenToYuan(Long.parseLong(amount)));
            x.put("customerId", customerId);

            List<Map<String, Object>> temp = xbMerchantMapper.tradeList(x);
            temp.forEach(m -> {
                String refundAmount = m.get("amount") == null ? "0" : m.get("amount").toString();
                m.put("amount", NumberUtils.fenToYuan(Long.parseLong(refundAmount)));
                if("vip".equals(m.get("refundNo"))){
                    String oSn = x.get("orderSn").toString();
                    m.put("refundNo","wq"+oSn.substring(1)+customerId);
                    m.put("protect_code","wq"+oSn.substring(1)+customerId);
                }
            });
            x.remove("customerId");
            x.put("refundList", temp);
        });
        return new PageInfo<>(result);
    }

    @Override
    public Long getCustomerFreeze(Map<String, Object> params) {
        Long customerFreeze = 0l;
        String customerId = params.get("customerId").toString();
        //String customerId = "C20200527jo8Ag6";
        List<Map<String, Object>> result = merchantSalerService.getOrderListFreeze(params);
        for (Map<String, Object> x : result) {
            if (x.get("isEnd") != null && "0".equals(x.get("isEnd").toString())) {
                Long amount = 0l;
                if (x.get("amount") != null) {
                    amount = Long.valueOf(x.get("amount").toString());
                }
                customerFreeze = customerFreeze + amount;
            }
            String amount = x.get("amount") == null ? "0" : x.get("amount").toString();
            x.put("amount", NumberUtils.fenToYuan(Long.parseLong(amount)));
            x.put("customerId", customerId);
            List<Map<String, Object>> temp = xbMerchantMapper.tradeListFreeze(x);
            for (Map<String, Object> m : temp) {
                if (m.get("isEnd") != null && "0".equals(m.get("isEnd").toString())) {
                    if (m.get("refundStatus") != null && "2".equals(m.get("refundStatus").toString())) {
                        Long refundAmount = 0l;
                        if (m.get("amount") != null) {
                            refundAmount = Long.valueOf(m.get("amount").toString());
                        }
                        customerFreeze = customerFreeze - refundAmount;
                    }
                }
            }
        }
        return customerFreeze;
    }

    @Override
    public void exportTradelist(Map<String, Object> params, HttpServletResponse response) {
        String customerId = params.get("customerId").toString();
        List<Map<String, Object>> result = merchantSalerService.getOrderListFreeze(params);
        result.forEach(x -> {
            String amount = x.get("amount") == null ? "0" : x.get("amount").toString();
            x.put("amount", NumberUtils.fenToYuan(Long.parseLong(amount)));
            x.put("customerId", customerId);

            List<Map<String, Object>> temp = xbMerchantMapper.tradeList(x);
            temp.forEach(m -> {
                String refundAmount = m.get("amount") == null ? "0" : m.get("amount").toString();
                m.put("amount", NumberUtils.fenToYuan(Long.parseLong(refundAmount)));
                if("vip".equals(m.get("refundNo"))){
                    String oSn = x.get("orderSn").toString();
                    m.put("refundNo","wq"+oSn.substring(1)+customerId);
                    m.put("protect_code","wq"+oSn.substring(1)+customerId);
                }
            });
            x.remove("customerId");
            x.put("refundList", temp);
        });
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
            String date = sdf.format(new Date());
            String title = "交易明细" + date;
            exportTradeXls(title, response, result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportTradeXls(
            String title1, HttpServletResponse response,List<Map<String, Object>> result)
            throws Exception {
        // 第一步，创建一个HSSFWorkbook，对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();

        // 第二步，在workbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet(title1);
        for (int i = 0; i < 47; i++) {
            sheet.setColumnWidth(i, 256 * 20 + 184);
        }
        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
        HSSFRow row = sheet.createRow(0);
        // 第四步，创建单元格，并设置值表头 设置表头居中
        HSSFCellStyle cellStyle = wb.createCellStyle();
        // 设置背景色
        cellStyle.setFillForegroundColor((short) 13);
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

        cellStyle.setBottomBorderColor(IndexedColors.BLACK.index);
        cellStyle.setTopBorderColor(IndexedColors.BLACK.index);
        cellStyle.setLeftBorderColor(IndexedColors.BLACK.index);
        cellStyle.setRightBorderColor(IndexedColors.BLACK.index);
        // 下边框
        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        // 左边框
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 右边框
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

        // HSSFCellStyle style = wb.createCellStyle();
        // 创建一个居中格式
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        HSSFCellStyle cellStyleR = wb.createCellStyle();
        cellStyleR.setBottomBorderColor(IndexedColors.BLACK.index);
        cellStyleR.setTopBorderColor(IndexedColors.BLACK.index);
        cellStyleR.setLeftBorderColor(IndexedColors.BLACK.index);
        cellStyleR.setRightBorderColor(IndexedColors.BLACK.index);
        cellStyleR.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        cellStyleR.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        cellStyleR.setBorderTop(HSSFCellStyle.BORDER_THIN);
        cellStyleR.setBorderRight(HSSFCellStyle.BORDER_THIN);

        // HSSFCellStyle style = wb.createCellStyle();
        // 创建一个居中格式
        cellStyleR.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        HSSFFont font = wb.createFont();
        font.setFontName("黑体");
        // 设置字体大小
        font.setFontHeightInPoints((short) 14);
        cellStyle.setFont(font);
        // 声明列对象
        HSSFCell cell = null;
//        String[] title = {
//                "商品名称", "单价", "数量", "规格", "售后", "商品总价", "收货人", "收货人电话", "收货人地址", "实付金额", "订单状态", "订单类型",
//                "订单号", "下单时间","供货商","备注"
//        };
        String[] title = {
                "时间", "名称", "订单号|支付单号", "金额(元)|明细", "状态"
        };
        // 创建标题
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(cellStyle);
        }
        for (int i = 0; i < title.length; i++) {
            Integer startrow = 0;
            Integer overrow = 0;
            Integer startcol = i;
            Integer overcol = i;
            sheet.addMergedRegion(new CellRangeAddress(startrow, overrow, startcol, overcol));
        }

        int count = 1;
        for (Map<String, Object> trade : result) {
            int starcount = count;
            int endcount = count;
            List<Map<String, Object>> refundlist =( List<Map<String, Object>>) trade.get("refundList");
            row = sheet.createRow(count);
            cell = row.createCell(0);
            cell.setCellStyle(cellStyleR);
            String createTimeString = "";
            if(!StringUtils.isEmpty(trade.get("createTime"))){
                createTimeString = trade.get("createTime").toString().substring(0,19);
            }
            cell.setCellValue(createTimeString);
            cell = row.createCell(1);
            cell.setCellStyle(cellStyleR);
            String orderName = "";
            if(!StringUtils.isEmpty(trade.get("orderName"))){
                orderName = trade.get("orderName").toString();
            }
            cell.setCellValue(orderName);
            cell = row.createCell(2);
            cell.setCellStyle(cellStyleR);
            String orderSn = "";
            if(!StringUtils.isEmpty(trade.get("orderSn"))){
                orderSn = trade.get("orderSn").toString();
            }
            if(!StringUtils.isEmpty(trade.get("serialNo"))){
                orderSn = orderSn+"  |  "+trade.get("serialNo").toString();
            }
            cell.setCellValue(orderSn);
            cell = row.createCell(3);
            cell.setCellStyle(cellStyleR);
            String amount = "";
            if(!StringUtils.isEmpty(trade.get("amount"))){
                amount = trade.get("amount").toString();
            }
            cell.setCellValue(amount);
            cell = row.createCell(4);
            cell.setCellStyle(cellStyleR);
            String isEndString = "";
            if(!StringUtils.isEmpty(trade.get("isEnd"))){
                String isEnd = trade.get("isEnd").toString();
                if("0".equals(isEnd)){
                    isEndString = "待结算";
                }
                if("1".equals(isEnd)){
                    isEndString = "已结算";
                }
                if("2".equals(isEnd)){
                    isEndString = "结算关闭";
                }
            }
            cell.setCellValue(isEndString);
            count++;
            if(refundlist != null && refundlist.size() > 0){
                endcount = count + refundlist.size()-1;
                for(int j = 0; j < refundlist.size(); j++){
                    row = sheet.createRow(count);
                    cell = row.createCell(1);
                    cell.setCellStyle(cellStyleR);
                    orderName = "";
                    if(!StringUtils.isEmpty(refundlist.get(j).get("orderName"))){
                        orderName = refundlist.get(j).get("orderName").toString();
                    }
                    cell.setCellValue(orderName);
                    cell = row.createCell(2);
                    cell.setCellStyle(cellStyleR);
                    String refundNo = "";
                    if(!StringUtils.isEmpty(refundlist.get(j).get("refundNo"))){
                        refundNo = refundlist.get(j).get("refundNo").toString();
                    }
                    cell.setCellValue(refundNo);
                    cell = row.createCell(3);
                    cell.setCellStyle(cellStyleR);
                    amount = "";
                    if(!StringUtils.isEmpty(refundlist.get(j).get("amount"))){
                        amount = refundlist.get(j).get("amount").toString();
                    }
                    cell.setCellValue(amount);
                    cell = row.createCell(4);
                    cell.setCellStyle(cellStyleR);
                    String refundStatusString = "";
                    if(!StringUtils.isEmpty(refundlist.get(j).get("refundStatus"))){
                        String refundStatus = refundlist.get(j).get("refundStatus").toString();
                        if("1".equals(refundStatus)){
                            refundStatusString = "进行中";
                        }
                        if("2".equals(refundStatus)){
                            refundStatusString = "退款完成";
                        }
                    }
                    cell.setCellValue(refundStatusString);
                    count++;
                }
            }

            CellRangeAddress region = new CellRangeAddress(starcount, endcount, 0, 0);
            sheet.addMergedRegion(region);
            // 下边框   左边框  有边框  上边框
            RegionUtil.setBorderBottom(1, region, sheet, wb);
            RegionUtil.setBorderLeft(1, region, sheet, wb);
            RegionUtil.setBorderRight(1, region, sheet, wb);
            RegionUtil.setBorderTop(1, region, sheet, wb);
            RegionUtil.setBottomBorderColor(IndexedColors.BLACK.index, region, sheet, wb);
            RegionUtil.setLeftBorderColor(IndexedColors.BLACK.index, region, sheet, wb);
            RegionUtil.setRightBorderColor(IndexedColors.BLACK.index, region, sheet, wb);
            RegionUtil.setTopBorderColor(IndexedColors.BLACK.index, region, sheet, wb);
        }
        OutputStream output = response.getOutputStream();
        response.reset();
        response.setHeader(
                "Content-Disposition", "attachment;filename=" + URLEncoder.encode("交易明细列表.xls", "utf-8"));
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        String scrmH5Url = systemProperties.getAcsScrmWebUrl();
        if (scrmH5Url.endsWith("/")) {
            scrmH5Url = scrmH5Url.substring(0, scrmH5Url.length() - 1);
        }
        response.setHeader("Access-Control-Allow-Origin", scrmH5Url);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setCharacterEncoding("utf-8");
        wb.write(output);
        output.close();
    }

    @Override
    public String getShopName(Map<String, Object> map) {
        return xbMerchantMapper.getShopName(map);
    }

    @Override
    public String getShopNameAndLogo(Map<String, Object> map) {
        return xbMerchantMapper.getShopNameAndLogo(map);
    }
}
